//编写一个UdpSocket类，通过实例化对象能够简便的完成服务器以及客户端的搭建
#include<iostream>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/socket.h>
using namespace std;
class UdpSocket{
private:
    int _sockfd;
public:
    UdpSocket():_sockfd(-1){};
    ~UdpSocket(){Close();}
    bool Socket(){
        _sockfd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
        if(_sockfd<0){
            perror("socket error");
            return false;
        }
        return true;
    }
    bool Bind(const string &ip,uint16_t port){
        struct sockaddr_in addr;
        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);
        addr.sin_addr.s_addr=inet_addr(ip.c_str());
        socklen_t addrlen=sizeof(struct sockaddr_in);
        int ret=bind(_sockfd,(struct sockaddr*)&addr,addrlen);
        if(ret<0){
            perror("bind error");
            return false;
        }
        return true;
    }
    bool Send(const string &body,const string &ip,uint16_t port){
        struct sockaddr_in addr;
        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);
        addr.sin_addr.s_addr=inet_addr(ip.c_str());
        socklen_t addrlen=sizeof(struct sockaddr_in);
        ssize_t ret=sendto(_sockfd,body.c_str(),body.size(),0,(struct sockaddr*)&addr,addrlen);
        if(ret<0){
            perror("sendto error");
            return false;
        }
        return true;
    }
    bool Recv(string *body,string *ip=NULL,uint16_t *port=NULL){
        struct sockaddr_in addr;
        socklen_t addrlen=sizeof(struct sockaddr_in);
        char tmp[4096]={0};
        ssize_t ret=recvfrom(_sockfd,tmp,4096,0,(struct sockaddr*)&addr,&addrlen);
        if(ret<0){
        perror("recvfrom error");
        return false;
        }
        if(port!=NULL)
        *port=ntohs(addr.sin_port);
        if(ip!=NULL)
        *ip=inet_ntoa(addr.sin_addr);
        body->assign(tmp,ret);
        return true;
    }
    bool Close(){
        if(_sockfd<0){
            return true;
        }
        close(_sockfd);
        _sockfd=-1;
        return true;
    }
};